home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
169_01
/
usq.c86
< prev
next >
Wrap
Text File
|
1984-07-27
|
6KB
|
272 lines
/*% cc -O -n % -o usq
*/
char Version[] = {"usq revised 8-13-83"}; /* 1.7 */
/*
*
* 08/13/83 C86 Version by Wayne Fruhwald
* Converted to work with Computer Innovation's C86 c compiler under MSDOS.
*
*/
#include <stdio.h>
/* #include <signal.h> */ /* 1.7 */
/* #include <ctype.h> */ /* 1.7 */
#define TRUE 1
#define FALSE 0
#define ERROR (-1)
#define PATHLEN 312 /* Number of characters allowed in pathname */
#define OK 0
#define RECOGNIZE 0xFF76 /* unlikely pattern */
#define DLE 0x90 /* repeat byte flag */
#define SPEOF 256 /* special endfile token */
#define NUMVALS 257 /* 256 data values plus SPEOF*/
#define LARGE 30000
struct _sqleaf { /* Decoding tree */
int _children[2]; /* left, right */
};
struct _sqleaf Dnode[NUMVALS - 1];
int Bpos; /* last bit position read */
int Curin; /* last byte value read */
int Repct; /* Number of times to retirn value */
int Value; /* current byte value or EOF */
int MakeLCPathname=TRUE; /* translate pathname to lc if all caps */
int Nlmode=FALSE; /* zap cr's if true */
main(argc, argv)
char *argv[];
{
register char *cp;
register npats=0;
char **patts;
int n, errorstat;
errorstat=0;
if(argc<2)
goto usage;
while (--argc) {
cp = *++argv;
if(*cp == '-') {
while( *++cp) {
switch(*cp) {
case 'n':
Nlmode=TRUE; break;
case 'u':
MakeLCPathname=FALSE; break;
default:
goto usage;
}
}
}
else if( !npats && argc>0) {
if(argv[0][0]) {
npats=argc;
patts=argv;
}
}
}
if(npats < 1) {
usage:
fprintf(stderr,"Usage: usq [-nu] file ...\n");
fprintf(stderr,"\t-n Nlmode: remove carriage returns\n");
fprintf(stderr,"\tx-u preserve Uppercase pathnames\n");
exit(1);
}
for(n=0; n<npats; ++n)
errorstat |= squeeze(patts[n]);
exit(errorstat != 0);
}
/*
The following code is primarily from typesq.c and utr.c. Typesq
is a modification of USQ by Dick Greenlaw. Those modifications (usq
to typesq) were made by Bob Mathias, I am responsible for the butchery
done to make it work with cat.
*/
FILE *in, *out;
squeeze(fname)
char *fname;
{
register i, c;
register char *p;
register int numnodes; /* size of decoding tree */
register unsigned crc;
unsigned filecrc;
char origname[PATHLEN]; /* Original file name without drive */
init_cr(); init_huff(); crc=0;
if((in=fopen( fname, "rb"))==NULL) { /* 1.7 */
fprintf(stderr, "usq: can't open %s\n", fname);
return ERROR;
}
if(portgetw(in) != RECOGNIZE) { /* Process header */
fprintf(stderr, "usq: %s is not a SQueezed file\n", fname);
return ERROR;
}
filecrc=portgetw(in); /* checksum */
p = origname; /* Get original file name */
do { /* send it to array */
*p = getc(in);
} while(*p++ != '\0');
numnodes = portgetw(in);
if(numnodes < 0 || numnodes >= NUMVALS) {
fprintf(stderr, "usq: %s has invalid decode tree\n", fname);
fclose(in);
return ERROR;
}
/* Initialize for possible empty tree (SPEOF only) */
Dnode[0]._children[0] = -(SPEOF + 1);
Dnode[0]._children[1] = -(SPEOF + 1);
for(i = 0; i < numnodes; ++i) { /* Get decoding tree from file */
Dnode[i]._children[0] = portgetw(in);
Dnode[i]._children[1] = portgetw(in);
}
/* Get translated output bytes and write file */
if(MakeLCPathname && !IsAnyLower(origname))
uncaps(origname);
fprintf(stderr, "usq: %s -> %s\n",fname,origname);
if((out=fopen(origname, "wb"))==NULL) { /* 1.7 */
fprintf("usq: can't create %s\n", origname);
}
while ((c = getcr()) != EOF) {
crc += c;
if ( c == '\r' && Nlmode)
continue;
putc(c, out);
}
fclose(in);
fflush(out);
fclose(out);
if( crc != filecrc ) {
fprintf(stderr, "usq: bad checksum in %s\n", fname);
return ERROR;
}
return OK;
}
/*** from utr.c - */
/* initialize decoding functions */
init_cr()
{
Repct = 0;
}
init_huff()
{
Bpos = 99; /* force initial read */
}
/* Get bytes with decoding - this decodes repetition,
* calls getuhuff to decode file stream into byte
* level code with only repetition encoding.
*
* The code is simple passing through of bytes except
* that DLE is encoded as DLE-zero and other values
* repeated more than twice are encoded as value-DLE-count.
*/
int
getcr()
{
register c;
if(Repct > 0) {
/* Expanding a repeated char */
--Repct;
return Value;
} else {
/* Nothing unusual */
if((c = getuhuff()) != DLE) {
/* It's not the special delimiter */
Value = c;
if(Value == EOF)
Repct = LARGE;
return Value;
} else {
/* Special token */
if((Repct = getuhuff()) == 0)
/* DLE, zero represents DLE */
return DLE;
else {
/* Begin expanding repetition */
Repct -= 2; /* 2nd time */
return Value;
}
}
}
}
/* Decode file stream into a byte level code with only
* repetition encoding remaining.
*/
int
getuhuff()
{
register i;
register bitval;
/* Follow bit stream in tree to a leaf*/
i = 0; /* Start at root of tree */
do {
if(++Bpos > 7) {
if((Curin = getc(in)) == ERROR)
return ERROR;
Bpos = 0;
/* move a level deeper in tree */
i = Dnode[i]._children[1 & Curin];
} else
i = Dnode[i]._children[1 & (Curin >>= 1)];
} while(i >= 0);
/* Decode fake node index to original data value */
i = -(i + 1);
/* Decode special endfile token to normal EOF */
i = (i == SPEOF) ? EOF : i;
return i;
}
/*
* Machine independent getw which always gets bytes in the same order
* as the CP/M version of SQ wrote them
*/
portgetw(f)
FILE *f;
{
register c;
c = getc(f)&0377;
return c + (getc(f)<<8);
}
/* make string s lower case */
uncaps(s)
register char *s;
{
for( ; *s; ++s)
if(isupper(*s))
*s = tolower(*s);
}
/*
* IsAnyLower returns TRUE if string s has lower case letters.
*/
IsAnyLower(s)
register char *s;
{
for( ; *s; ++s)
if (islower(*s))
return TRUE;
return FALSE;
}